#include "chooserwidget.h"
#include "ui_chooserwidget.h"
#include "chooseditthemes.h"
#include "choosedittasks.h"
#include "choosdictionary.h"
#include <QMessageBox>
#include <QDebug>

ChooserWidget::ChooserWidget(QWidget *parent) :
    QStackedWidget(parent),
    ui(new Ui::ChooserWidget)
{
    ui->setupUi(this);
    ui->frame_DictPref->setVisible(false);
    setCurrentIndex(0);
    buttonsList << ui->mixButton0
                << ui->mixButton1
                << ui->mixButton2
                << ui->mixButton3
                << ui->mixButton4
                << ui->mixButton5;
    for (int i = 0; i < 6; ++i) {
        connect(buttonsList.at(i), SIGNAL(clicked()), this, SLOT(chooseButtonsClicked()));
        connect(buttonsList.at(i), SIGNAL(rightClicked(QString)), this, SLOT(chooseButtonsRightClicked()));
        buttonsList.at(i)->setIconSize(QSize(20, 20));
    }
    startpanelFill();
}

ChooserWidget::~ChooserWidget()
{
    delete ui;
}

void ChooserWidget::settingsReloadFromMainSlot()
{
    ui->retranslateUi(this);
}

void ChooserWidget::on_pushButtonCloseInGame_clicked()
{
    deleteLater();
}

void ChooserWidget::startpanelFill()
{
    themeSqlModel.setQuery("SELECT * FROM chooser_themes ORDER BY teng");
    themeSqlModel.setHeaderData(1, Qt::Horizontal, tr("Theme-English"));
    themeSqlModel.setHeaderData(2, Qt::Horizontal, tr("Theme-Hungarian"));
    ui->tableView_ThemeSelector->setModel(&themeSqlModel);
    ui->tableView_ThemeSelector->hideColumn(0);
    ui->tableView_ThemeSelector->horizontalHeader()->setResizeMode(1, QHeaderView::Stretch);
    ui->tableView_ThemeSelector->horizontalHeader()->setResizeMode(2, QHeaderView::Stretch);
}

void ChooserWidget::on_pushButtonClose_clicked()
{
    deleteLater();
}

void ChooserWidget::on_commandLinkButtonStartMixer_clicked()
{
    QString querystring;
    if (ui->radioButton_Dictionary->isChecked()) {
//        QMessageBox::information(this, "Function unavailable", "The dictionary mode is unavailable currently.");
        querystring = "SELECT id FROM dictionary";
//        return; //word learning
    }
    else
        querystring = "SELECT id FROM chooser";
    QStringList themeIdList_string;
    if (ui->radioButton_SelectedThemes->isChecked()) {
        QItemSelectionModel *selectionModel = ui->tableView_ThemeSelector->selectionModel();
        QModelIndexList indexes = selectionModel->selectedRows();
        int selnr = indexes.count();
        for (int i = 0; i < selnr; ++i)
            themeIdList_string << themeSqlModel.record(indexes.at(i).row()).value(0).toString();
        querystring += " WHERE tid in (" + themeIdList_string.join(",") + ")";
    }
    model.setQuery(querystring);
    while (model.canFetchMore())
        model.fetchMore();
    numberofSumTasks = model.rowCount();
    if (numberofSumTasks == 0) {
        QString message(tr("Selection set is empty!\nChoose other selection or add themes/tasks using Edit buttons!"));
        QMessageBox::information(this, tr("Empty selection"), message);
        return;
    }
    QList<int> tmpTasksIdList;
    for (int i = 0; i < numberofSumTasks; ++i)
        tmpTasksIdList << model.record(i).value("id").toInt();
    tasksIdList.clear();
    if (ui->radioButton_AllTasks->isChecked())
        tasksIdList = tmpTasksIdList;
    else if (ui->radioButton_RandomFromAll->isChecked()) {
        for (int i = 0; i < ui->spinBox_Random->value(); ++i) {
            int tmpSIDListCount = tmpTasksIdList.count();
            if (tmpSIDListCount == 0)
                break;
            int value = tmpTasksIdList.takeAt(qrand() % tmpSIDListCount);
            tasksIdList.append(value);
        }
    }
    else if (ui->radioButton_RandomPerTheme->isChecked()) {
        QList<int> themeIdList_number;
        if (ui->radioButton_AllThemes->isChecked()) {
            QSqlQuery query("SELECT tid FROM chooser_themes");
            while (query.next())
                themeIdList_number << query.value(0).toInt();
        }
        else
            for (int i = 0; i < themeIdList_string.count(); ++i)
                themeIdList_number << themeIdList_string.at(i).toInt();
        int numberOfUsedThemes = themeIdList_number.count();
        int needRecords = ui->spinBox_RandomPerTheme->value();
        for (int i = 0; i < numberOfUsedThemes; ++i) {
            QSqlQuery query;
            query.prepare("SELECT id FROM chooser where tid=:themeid");
            query.bindValue(0, themeIdList_number.at(i));
            query.exec();
            tmpTasksIdList.clear();
            while (query.next())
                tmpTasksIdList << query.value(0).toInt();
            int recordCount = 0;
            while (tmpTasksIdList.count() && recordCount < needRecords) {
                ++recordCount;
                tasksIdList << tmpTasksIdList.takeAt(qrand() % tmpTasksIdList.count());
            }
        }
    }
    numberofSumTasks = tasksIdList.count();
    if (ui->radioButton_FreePlay->isChecked()) {
        ui->progressBar_Done->hide();
        ui->label_Playmode->setText(tr("Freeplay"));
    }
    else {
        ui->progressBar_Done->show();
        ui->progressBar_Done->setMaximum(numberofSumTasks);
        if (ui->checkBox_Learning->isChecked())
            ui->label_Playmode->setText(tr("Learning"));
        else
            ui->label_Playmode->setText(tr("All at Once"));
    }
    clearDisplayCounters();
    isInGame = true;
    startNewTask();
    setCurrentIndex(1);
}

void ChooserWidget::updateStatisticDisplays()
{
    ui->label_SentencesNr->setText(QString::number(numberofSumTasks));
    ui->label_Done->setText(QString::number(countDone));
    ui->label_False->setText(QString::number(countFalse));
    int performancePercent = (countDone > 0) ? countDone*100/(countDone+countFalse) : 0;
    ui->label_Performance->setText(QString::number(performancePercent) + "%");
    ui->progressBarPerformance->setValue(performancePercent);
    if (ui->progressBar_Done->isVisible())
        ui->progressBar_Done->setValue(countDone);
}

void ChooserWidget::clearDisplayCounters()
{
    countDone = 0;
    countFalse = 0;
    updateStatisticDisplays();
}

void ChooserWidget::on_pushButton_ChangeMode_clicked()
{
    setCurrentIndex(0);
}

void ChooserWidget::on_pushButton_EditThemes_clicked()
{
    ChoosEditThemes editThemesDialog(this);
    editThemesDialog.exec();
    startpanelFill();
}

void ChooserWidget::on_pushButton_EditSentences_clicked()
{
    ChoosEditTasks editTasksDialog(this);
    editTasksDialog.exec();
}

void ChooserWidget::on_pushButton_EditDictionary_clicked()
{
    this->setCursor(Qt::WaitCursor);
    ChoosDictionary dictionaryDialog(this);
    dictionaryDialog.exec();
    this->setCursor(Qt::ArrowCursor);
}

void ChooserWidget::startNewTask(int currentID)
{
    TaskComponents taskComponents;
    correctButtonsList.clear();
    getNewTask(taskComponents, currentID);
    QString theme(taskComponents.themeEN);
    theme.append(" | ");
    theme.append(taskComponents.themeHU);
    ui->label_ThemeName->setText(theme);
    if (taskComponents.isTrueOrFalse)
        ui->label_CorrectOrIncorrect->setText(tr("Which is correct?"));
    else
        ui->label_CorrectOrIncorrect->setText(tr("Which is wrong?"));
    ui->label_Challenge->setText(taskComponents.question);
    int numAnswers = taskComponents.answers.count();
    currentButtonsAvailable = numAnswers;
    QList<int> tmpl; //randomize answare buttons
    for (int i = 0; i < 6; ++i)
        tmpl.append(i);
    for (int i = 0; i < 40; ++i) {
        int p = qrand() % numAnswers;
        tmpl.swap(0, p);
    }
    if (numAnswers < 5) {
        tmpl.swap(tmpl.indexOf(0), numAnswers);
        if (numAnswers == 2)
            tmpl.swap(tmpl.indexOf(1), numAnswers + 1);
    }
    for (int i = 0; i < numAnswers; ++i) {
        int btn = tmpl.takeFirst();
        if (taskComponents.correctAnswerIDs.contains(i+1)) // +1 because answer id's in db is 1-6
            correctButtonsList << buttonsList[btn];
        buttonsList.at(btn)->setText(taskComponents.answers.at(i));
        buttonsList.at(btn)->setFlat(false);
        buttonsList.at(btn)->setmarked(false);
        if (taskComponents.isTrueOrFalse)
            buttonsList.at(btn)->setIcon(QIcon(QPixmap(":/images/question-icon_green.png")));
        else
            buttonsList.at(btn)->setIcon(QIcon(QPixmap(":/images/question-icon_red.png")));
    }
    while (tmpl.count()) {
        int btn = tmpl.takeFirst();
        buttonsList.at(btn)->setText("");
        buttonsList.at(btn)->setFlat(true);
        buttonsList.at(btn)->setmarked(false);
        buttonsList.at(btn)->setIcon(QIcon(QPixmap()));
    }
    qApp->setStyleSheet(qApp->styleSheet());
}

void ChooserWidget::getNewTask(TaskComponents &components, int currentID)
{
    int tasksCount = tasksIdList.count();
    if (currentID == 0) {
        currentListIndex = qrand() % tasksCount;
        currentID = tasksIdList.at(currentListIndex);
    }
    else
        currentListIndex = tasksIdList.indexOf(currentID);
    currentTaskID = currentID;
    currentTaskIsOnlyTrue = true;
    QSqlQuery query;
    if (ui->radioButton_Dictionary->isChecked()) { //dictionary mode
        components.themeEN = tr("Word learning");
        components.themeHU = tr("Dictionary mode");
        components.isTrueOrFalse = 1;
        components.correctAnswerIDs << 1;
        query.prepare("SELECT eng, hun FROM dictionary WHERE id=:id");
        query.bindValue(0, currentID);
        query.exec();
        query.next();
        int directionMode = 0;
        switch (ui->comboBox_LangDirection->currentIndex()) {
        case 0:
            directionMode = 0;
            break;
        case 1:
            directionMode = 1;
            break;
        case 2:
            directionMode = qrand() % 2;
            break;
        }
        components.question = query.value(directionMode).toString().simplified();
        components.answers << query.value(!directionMode).toString().simplified();
        query.prepare("SELECT eng, hun FROM dictionary WHERE id<>:id order by random() LIMIT :limit");
        query.bindValue(0, currentID);
        query.bindValue(1, ui->lcdNumber_DictWords->value() - 1);
        query.exec();
        while (query.next())
            components.answers << query.value(!directionMode).toString().simplified();
    }
    else { //normal mode
        query.prepare("SELECT teng, thun, type, correct, question, answer1, answer2, answer3, answer4, answer5, answer6 FROM chooser, chooser_themes WHERE id=:id AND chooser.tid=chooser_themes.tid");
        query.bindValue(0, currentID);
        query.exec();
        query.next();
        components.themeEN = query.value(0).toString().simplified();
        components.themeHU = query.value(1).toString().simplified();
        components.isTrueOrFalse = query.value(2).toBool();
        //number id's of correct answers
        QString correctstring(query.value(3).toString());
        int correctstrlen = correctstring.length();
        for (int i = 0; i < correctstrlen; ++i)
            components.correctAnswerIDs << correctstring.at(i).digitValue();
        //challange question
        components.question = query.value(4).toString().simplified();
        //answers
        for (int i = 5; i <= 10; ++i) {
            QString answer = query.value(i).toString().simplified();
            if (!answer.isEmpty())
                components.answers.append(answer);
        }
    }
}

void ChooserWidget::endGame()
{
    for (int i = 0; i < 6; ++i) {
        buttonsList.at(i)->setText("");
        buttonsList.at(i)->setIcon(QIcon(QPixmap()));
        ui->label_CorrectOrIncorrect->setText("");
        ui->label_Challenge->setText(tr("Mission completed!"));
    }
}

void ChooserWidget::on_pushButton_Next_clicked()
{
    if (isInGame)
        startNewTask();
    else
        endGame();
}

void ChooserWidget::chooseButtonsClicked()
{
    if (correctButtonsList.isEmpty()) {
        if (isInGame)
            startNewTask();
        else
            endGame();
        return;
    }
    RightClickableButton *clickedButton = qobject_cast<RightClickableButton*>(sender());
    if (clickedButton->isFlat())
        return;
    --currentButtonsAvailable;
    bool lastClick = false;
    if (currentButtonsAvailable == 1)
        lastClick = true;
    else if (ui->radioButton_OneClickPerTask->isChecked())
        lastClick = true;
    if (correctButtonsList.contains(clickedButton)) { // correct click
        correctButtonsList.removeOne(clickedButton);
        clickedButton->setIcon(QIcon(QPixmap(":/images/correct-icon.png")));
        if (ui->radioButton_OneClickPerTask->isChecked() || ! ui->checkBox_MustAllCorrect->isChecked())
            correctButtonsList.clear();
    }
    else { // false click
        clickedButton->setIcon(QIcon(QPixmap(":/images/wrong-icon.png")));
        clickedButton->setFlat(true);
        ++countFalse;
        currentTaskIsOnlyTrue = false;
        if (ui->radioButton_OneClickPerTask->isChecked()) {
            lastClick = true;
            correctButtonsList.clear();
        }
        if (lastClick && ui->radioButton_OneIsOneTimes->isChecked() && ! ui->checkBox_Learning->isChecked())
            tasksIdList.removeAt(currentListIndex);
        if (lastClick && ui->radioButton_FreePlay->isChecked())
            ++countDone;
    }
    if (correctButtonsList.isEmpty()) { //task done
        lastClick = true;
        ++countDone;
        if (ui->radioButton_OneIsOneTimes->isChecked()) {
            if (! ui->checkBox_Learning->isChecked() || currentTaskIsOnlyTrue)
                tasksIdList.removeAt(currentListIndex);
            if (ui->checkBox_Learning->isChecked() && ! currentTaskIsOnlyTrue)
                --countDone;
        }
    }
    if (lastClick) {
        for (int i = 0; i < 6; ++i) {
            buttonsList.at(i)->setFlat(true);
            buttonsList.at(i)->setmarked(true);
            qApp->setStyleSheet(qApp->styleSheet());
        }
        correctButtonsList.clear(); //end of this task
    }
    updateStatisticDisplays();
    if (tasksIdList.count() == 0)
        isInGame = false;
}

void ChooserWidget::chooseButtonsRightClicked()
{
    RightClickableButton *clickedButton = qobject_cast<RightClickableButton*>(sender());
    clickedButton->setmarked(!clickedButton->ismarked());
    qApp->setStyleSheet(qApp->styleSheet());
}

void ChooserWidget::on_radioButton_Dictionary_toggled(bool checked)
{
    if (checked && ui->radioButton_RandomPerTheme->isChecked())
        ui->radioButton_RandomFromAll->setChecked(true);
}
